package ldh.im.fxgui.pane;

import com.fluxvend.svgfx.SvgImageView;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.text.TextAlignment;
import ldh.im.ImConfig;
import ldh.im.dto.enums.MessageType;
import ldh.im.fxbase.controller.VideoPlayerController;
import ldh.im.fxbase.data.pojo.ImMessage;
import ldh.im.fxbase.data.pojo.status.ImMessageFileStatus;
import ldh.im.fxbase.richtext.ImText;
import ldh.im.fxbase.util.*;
import ldh.im.fxgui.component.ImStage;
import ldh.im.fxgui.service.DefaultFileProgressListener;
import ldh.im.fxgui.util.UiUtil;
import ldh.rpc.cache.CacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.function.Supplier;

public class VideoMessagePane extends BaseMessagePane {

    private static final Logger LOGGER = LoggerFactory.getLogger(VideoMessagePane.class);

    @Override
    public Node createPane(ImMessage message, boolean isReceive, boolean isRef) {
        if (message.getMessageType() != MessageType.Video) {
            throw new RuntimeException("不支持这种消息类型" + message.getMessageType());
        }
        if (message.isSender(message.getCurrentUserId())) {
            if (message.getFileStatus() != ImMessageFileStatus.uploaded) {
                TextAlignment textAlignment = TextAlignment.LEFT; //isReceive ? TextAlignment.LEFT : TextAlignment.RIGHT;
                ImText imText = new ImText(textAlignment);
                imText.setImContent("视频正在上传中");
                return imText;
            }
        } else {
            if (message.getFileStatus() != ImMessageFileStatus.downloaded) {
                TextAlignment textAlignment = TextAlignment.LEFT; //isReceive ? TextAlignment.LEFT : TextAlignment.RIGHT;
                ImText imText = new ImText(textAlignment);
                imText.setImContent("视频正在下载中");
                return imText;
            }
        }

        StackPane stackPane = new StackPane();
        if (isReceive) {
            stackPane.setAlignment(Pos.CENTER_LEFT);
        } else {
            stackPane.setAlignment(Pos.CENTER_RIGHT);
        }

//        stackPane.getStyleClass().add("im-text-pane");

        MediaView mediaView = new MediaView();
        String path = FileUtil.getFilePath(message);
        setMediaPlayer(mediaView, path);
        mediaView.setFitWidth(200);
        mediaView.setFitHeight(100);

        SvgImageView playView = new SvgImageView();
        playView.setColor("#ffffff");
        playView.setPrefSize(30, 30);
        try {
            playView.setSvg(this.getClass().getResource("/im-svg/play.svg").toExternalForm());
        } catch (Exception e) {
            LOGGER.error("get play.svg error", e);
        }

        if (!isRef) {
            mediaView.setOnMouseClicked(e-> showVideoPlayPage(message));
            playView.setOnMouseClicked(e-> showVideoPlayPage(message));
            buildPopup(stackPane, message);
        }

        stackPane.getChildren().addAll(mediaView, playView);
        StackPane.setAlignment(playView, Pos.CENTER);
        stackPane.setMaxWidth(ParamUtil.MESSAGE_WIDTH);
        return stackPane;
    }

    private void playVideoEvent(ImMessage message, MediaView mediaView, Label videoLabel) {
        CacheService cacheService = RpcUtil.getRpcBootstrap().getRpcConfig().getCacheService();
        String currentUserId = (String) cacheService.getCache(ImConfig.LOGIN_USER_ID);
        if (message.isReceiver(currentUserId) && message.getFileStatus() != ImMessageFileStatus.downloaded) {
            ThreadPoolUtil.submit(()->{
                ExceptionUtil.catchException(()->{
                    RpcUtil.getImService().downloadFile(message, new DefaultFileProgressListener(), m-> UiUtil.uiUpdateMessage(m));
                    return null;
                });
            });
            return;
        }
        if (videoLabel.getUserData() != null && videoLabel.getUserData().toString().equals("playing")) return;
        videoLabel.setUserData("playing");
        String audioPath = FileUtil.getFilePath(message);
        playVideo(mediaView, audioPath, ()-> {
            videoLabel.setUserData("end!");
            return true;
        });
    }

    void playVideo(MediaView mediaView, String audioPath, Supplier<Boolean> supplier) {
        if (audioPath == null) return;
        File file = new File(audioPath);
        Media media = new Media(file.toURI().toString());
        MediaPlayer mediaPlayer = new MediaPlayer(media);
        mediaView.setMediaPlayer(mediaPlayer);
        mediaPlayer.onEndOfMediaProperty().set(()->{
            supplier.get();
        });
        mediaPlayer.setAutoPlay(true);
    }

    private void setMediaPlayer(MediaView mediaView, String videoPath) {
        try {
            File file = new File(videoPath);
            Media media = new Media(file.toURI().toString());
            MediaPlayer mediaPlayer = new MediaPlayer(media);
            mediaView.setMediaPlayer(mediaPlayer);
        } catch (Exception e) {
            LOGGER.error("play video error, video path: {}", videoPath);
            LOGGER.error("play video error", e);
        }
    }

    private void showVideoPlayPage(ImMessage message) {
        String mediaPath = FileUtil.getFilePath(message);
        ImStage stage = new ImStage(600, 400);;

        stage.setTitle("视频预览");
        stage.getCurrentScene().getStylesheets().add(this.getClass().getResource("/css/video-player.css").toExternalForm());
        RegionUtil.FxmlBean<Node, VideoPlayerController> fxmlBean =
                RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/VideoPlayerPage.fxml"));

        fxmlBean.getController().setStage(stage);
        fxmlBean.getController().play(mediaPath);
        stage.setContent(fxmlBean.getNode());

        stage.setOnCloseRequest((e)->{
            LOGGER.info("imStage close!!!");
            fxmlBean.getController().dispose();
            fxmlBean.getController().setStage(null);
            stage.close();
        });
        stage.show();
    }
}
